<?php
// +----------------------------------------------------------------------
// | Options服务服务层
// +----------------------------------------------------------------------
// | 主要服务于Options数据处理
// +----------------------------------------------------------------------
// | 错误编码头 214xxx
// +----------------------------------------------------------------------
namespace common\service;

use common\exception\LogicException;
use common\model\OptionsModel;
use common\model\StatusModel;
use Exception;
use support\SingletonTrait;
use support\ErrorCode;
use think\Cache;

class OptionsService
{
    // 合同业务模式
    const BUSINESS_MODE_BOTH_SIDES = 'both_sides_mode'; // 双方模式
    const BUSINESS_MODE_TRIPARTITE = 'tripartite_mode'; // 三方模式

    // 单例模式工具
    use SingletonTrait;

    /**
     * 获取指定Options设置
     * @param $optionName
     * @return mixed
     */
    public function getOptionsData($optionName)
    {
        $resData = model(OptionsModel::class)->field("config")->where(['name' => $optionName])->cache('option_query_cache:' . $optionName, C('database.default_query_cache_time'))->find();
        if (!empty($resData)) {
            CommonService::getFormatAttrData(model(OptionsModel::class), $resData);
        }
        return is_array($resData) && array_key_exists("config", $resData) ? $resData['config'] : [];
    }

    /**
     * 清除查询配置缓存
     * @param $optionNames
     * @return void
     */
    public function clearOptionCache($optionNames = [])
    {
        foreach ($optionNames as $optionName) {
            Cache::rm('option_query_cache:' . $optionName);
        }
    }

    /**
     * 获取系统模式配置
     * @param bool $isPageAuth
     * @return array
     */
    public function getSystemModeConfig($isPageAuth = true)
    {
        $defaultModeConfig = $this->getOptionsData("default_mode");
        if (empty($defaultModeConfig)) {
            $defaultModeConfig = [
                "mode" => "strack",
                "open_create_project" => "1",
                "visit_system_admin" => "1",
                "open_clone_project" => "0",
                "open_register" => "0",
                "default_role" => "0",
                "default_clone_project" => "0",
                "default_project_public" => "yes"
            ];
        }

        if ($isPageAuth) {
            $pageAuth = [
                'add_project' => 'yes',
                'visit_system_admin' => 'yes',
            ];
            if ($defaultModeConfig["open_register"] == 1 && $defaultModeConfig["open_create_project"] == 0) {
                $pageAuth["add_project"] = 'no';
            }
            if ($defaultModeConfig["open_register"] == 1 && $defaultModeConfig["visit_system_admin"] == 0) {
                $pageAuth["visit_system_admin"] = 'no';
            }

            return $pageAuth;
        } else {
            return $defaultModeConfig;
        }
    }

    /**
     * 获取指定Options设置项值
     * @param $optionName
     * @param $itemName
     * @param string $default
     * @return string
     */
    public function getOptionsConfigItemData($optionName, $itemName, $default = '')
    {
        $configData = $this->getOptionsData($optionName);
        if (!empty($configData) && array_key_exists($itemName, $configData)) {
            return $configData["$itemName"];
        } else {
            return $default;
        }
    }

    /**
     * 获取指定Options设置项值
     * @param $optionName
     * @param array $itemNames
     * @return array
     */
    public function getOptionsConfigMultiItemData($optionName, array $itemNames)
    {
        $configData = $this->getOptionsData($optionName);
        $res = array_fill_keys($itemNames, null);
        foreach ($res as $ck => &$cv) {
            if (array_key_exists($ck, $configData)) {
                $cv = $configData["$ck"];
            }
        }
        return $res;
    }

    /**
     * 通用更新修改Options
     * @param $params
     * @param string $message
     * @return array
     */
    public function updateOptionsData($params, $message = '')
    {
        $optionsModel = model(OptionsModel::class);
        $updateOptionResult = $optionsModel->updateOptionsData($params);
        if ($updateOptionResult) {
            if (empty($message)) {
                $message = 'Modify options success';
            }
            // 返回成功数据
            return success_response($message, $updateOptionResult);
        } else {
            // 添加更新系统配置失败错误码 001
            throw_strack_exception($optionsModel->getError(), ErrorCode::SYSTEM_CONFIG_UPDATE_FAILED);
        }
    }

    /**
     * 通用添加配置
     * @param $params
     * @param string $message
     * @return array
     * @throws Exception
     */
    public function addOptionsData($params, $message = '')
    {
        $optionsModel = model(OptionsModel::class);
        $findOptionsResult = $optionsModel->findData(["filter" => ["name" => $params['options_name']]]);
        if (empty($findOptionsResult)) {
            $addOptionsResult = $optionsModel->updateOptionsData($params);
            if ($addOptionsResult) {
                if (empty($message)) {
                    $message = $optionsModel->getSuccessMessage();
                }
                // 返回成功数据
                return success_response($message, $addOptionsResult);
            }

        } else {
            return $this->updateOptionsData($params);
        }
    }


    /**
     * 保存域登录服务配置
     * @param $param
     * @return array
     */
    public function saveLdapSetting($param)
    {
        $oldConfig = $this->getOptionsData("ldap_login_setting");
        switch ($param["type"]) {
            case "ldap_open":
                // 域服务登录开启
                if ($param["status"] == 1) {
                    $oldConfig["ldap_open"] = true;
                } else {
                    $oldConfig["ldap_open"] = false;
                }
                break;
            case "ldap_server_list":
                // 域服务器列表
                if (array_key_exists("ldap_server_list", $oldConfig)) {
                    switch ($param["status"]) {
                        case "on":
                            if (!in_array($param["ldap_id"], $oldConfig["ldap_server_list"])) {
                                array_push($oldConfig["ldap_server_list"], $param["ldap_id"]);
                            }
                            break;
                        case "off":
                            $newLdapServerList = [];
                            foreach ($oldConfig["ldap_server_list"] as $item) {
                                if ($item != $param["ldap_id"]) {
                                    array_push($newLdapServerList, $item);
                                }
                            }
                            $oldConfig["ldap_server_list"] = $newLdapServerList;
                            break;
                    }

                } else {
                    $oldConfig["ldap_server_list"] = [$param["ldap_id"]];
                }
                break;
        }

        $params = [
            "options_name" => "ldap_login_setting",
            "config" => $oldConfig
        ];

        // 更新域服务器配置
        return $this->updateOptionsData($params, 'LDAP domain login configuration settings are successful! ');
    }

    /**
     * 更新Ldap配置
     * @param $ids
     * @param string $mode
     */
    public function updateLdapSetting($ids, $mode = "delete")
    {
        $ldapOptions = $this->getOptionsData("ldap_login_setting");
        if (array_key_exists("ldap_server_list", $ldapOptions)) {
            $ldapOptionsIds = [];
            switch ($mode) {
                case "delete":
                    foreach ($ldapOptions["ldap_server_list"] as $ldapId) {
                        if (!in_array($ldapId, $ids)) {
                            array_push($ldapOptionsIds, $ldapId);
                        }
                    }

                    $ldapOptions["ldap_server_list"] = $ldapOptionsIds;

                    if (empty($ldapOptionsIds)) {
                        $ldapOptions["ldap_open"] = false;
                    }

                    break;
            }

            $params = [
                "options_name" => "ldap_login_setting",
                "config" => $ldapOptions
            ];

            $this->updateOptionsData($params);
        }
    }

    /**
     * 获取日志服务器状态
     * @return array
     * @throws Exception
     */
    public function getLogServerStatus()
    {
        $resData = teamones_request('teamones-im', 'options/get_event_log_server', null)['data'];
        if (!empty($resData["request_url"])) {
            $getServerStatus = check_http_code($resData["request_url"]);
            return [
                'status' => $getServerStatus['http_code'],
                'connect_time' => $getServerStatus['connect_time'],
                'name' => 'log server',
                'request_url' => $resData['request_url'],
                'websocket_url' => $resData['websocket_url'],
                'access_key' => $resData['access_key'],
                'secret_key' => $resData['secret_key']
            ];
        } else {
            return [];
        }
    }

    /**
     * 获取任务状态列表
     * @return array|mixed
     */
    public function getTaskStatusList()
    {
        $defaultStatusConfig = $this->getOptionsData("default_task_status");
        $statusList = [];
        if (!empty($defaultStatusConfig)) {
            $statusModel = model(StatusModel::class);
            $statusList = $statusModel->where(['code' => ['IN', join(',', array_values($defaultStatusConfig))]])->cache(C('database.default_query_cache_time'))->select();
        }
        return $statusList;
    }

    /**
     * 查询消息模板id
     * @param $itemName
     * @return string
     */
    public function getNotifyTemplateId($itemName)
    {
        return $this->getOptionsConfigItemData("message_notify_template_config", $itemName);
    }

    /**
     * 获取合同业务模式配置
     * @return mixed|null
     */
    public function getBusinessMode()
    {
        $data = teamones_request('teamones-im', 'options/get_business_mode', null);
        return $data['data'] ?? self::BUSINESS_MODE_BOTH_SIDES;
    }

    /**
     * 查询工序标准知识本配置id
     * @return string
     */
    public function getStepStandardBookTypeId()
    {
        return $this->getOptionsConfigItemData('step_standard_config', 'book_type_id');
    }

    /**
     * 获得贴图工序code
     * @return string[]
     */
    public function getTexStepCode()
    {
        return ['tex', 'texture'];
    }

    /**
     * 查询任务提醒通用通知模板
     * @return string
     */
    public function getTaskRemindCommonTemplateId()
    {
        return $this->getOptionsConfigItemData('message_notify_template_config', 'task_remind_common_template_id');
    }

    /**
     * 查询实体任务提醒通用通知模板
     * @return string
     */
    public function getEntityTaskRemindCommonTemplateId()
    {
        return $this->getOptionsConfigItemData('message_notify_template_config', 'entity_task_remind_common_template_id');
    }

    /**
     * 查询需求提醒通用通知模板
     * @return string
     */
    public function getDemandRemindCommonTemplateId()
    {
        return $this->getOptionsConfigItemData('message_notify_template_config', 'demand_remind_common_template_id');
    }

    /**
     * 获取生产环节配置
     * @return array|mixed
     */
    public function getProducerStepCategoryConfig($exceptionThrow = true)
    {
        $config = OptionsService::getInstance()->getOptionsData("producer_step_category_config");
        if ($exceptionThrow && empty($config)) {
            throw new LogicException("producer step category not config", ErrorCode::PRODUCER_STEP_CATEGORY_NOT_CONFIG);
        }
        return $config;
    }

    /**
     * 审核通过 通知返修环节组长 模板id
     * @return int
     */
    private function getNotifyTaskRepairOrderHeadmanToRepairTemplateId(): int
    {
        $messageTemplateId = OptionsService::getInstance()->getOptionsConfigItemData('message_notify_template_config', 'notify_task_repair_order_headman_to_repair_template_id');
        return (int)$messageTemplateId;
    }

    /**
     * 通知受影响任务执行人模板id
     * @return int
     */
    private function getNotifyTaskRepairOrderEffectedTaskExecutorTemplateId(): int
    {
        $messageTemplateId = OptionsService::getInstance()->getOptionsConfigItemData('message_notify_template_config', 'notify_task_repair_order_effected_task_executor_template_id');
        return (int)$messageTemplateId;
    }

    /**
     * 任务返修单审核结果通知模板id
     * @return int
     */
    private function getNotifyTaskRepairOrderReviewResultTemplateId(): int
    {
        $messageTemplateId = OptionsService::getInstance()->getOptionsConfigItemData('message_notify_template_config', 'notify_task_repair_order_review_result_template_id');
        return (int)$messageTemplateId;
    }

    /**
     * 返修单审核通知模板id
     * @return int
     */
    private function getNotifyTaskRepairOrderReviewTemplateId(): int
    {
        $messageTemplateId = OptionsService::getInstance()->getOptionsConfigItemData('message_notify_template_config', 'task_repair_order_review_template_id');
        return (int)$messageTemplateId;
    }
}
